package han.chensing.latos.maker.latos.file.util;

import han.chensing.latos.common.file.CirnoSerialize;
import han.chensing.latos.common.level.LatosProject;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ComParser {

    public static void writeToZipFile(LatosProject latosProject) throws IllegalAccessException, IOException {
        CirnoSerialize cirnoSerialize=new CirnoSerialize();
        JSONObject jsonObject = cirnoSerialize.serializeToJson(latosProject);
        File file = new File("out.lat");
        file.createNewFile();
        FileOutputStream fileOutputStream=new FileOutputStream(file);
        ZipOutputStream zipOutputStream=new ZipOutputStream(fileOutputStream);
        zipOutputStream.putNextEntry(new ZipEntry("music."+latosProject.getMusicFormat()));
        zipOutputStream.write(latosProject.getMusicBytes());
        zipOutputStream.closeEntry();
        zipOutputStream.putNextEntry(new ZipEntry("level.json"));
        zipOutputStream.write(jsonObject.toString().getBytes(StandardCharsets.UTF_8));
        zipOutputStream.closeEntry();
        zipOutputStream.close();
        fileOutputStream.close();
    }

    /*public static LatosLevel parseToComLevel(LatosProject latosProject){
        if (latosProject==null)return null;
        LatosLevel latosLevel=new LatosLevel();
        latosLevel.setMusicBytes(latosProject.getMusicBytes());
        latosLevel.setMusicFormat(latosProject.getMusicFormat());
        latosLevel.setMusicLength(latosProject.getMusicLength());
        handleLinesNotes(latosProject.getLevelData(),latosLevel.getElements());
        return latosLevel;
    }

    private static void handleLinesNotes(LevelData levelData, List<LatosLevelElement> elements){
        ArrayList<Line> lines = levelData.getLines();
        for (Line line : lines) {
            List<Frame> fakeKeyFrames=new ArrayList<>();
            LineElement lineElement=new LineElement();
            lineElement.setNum(line.getNum());
            handleLineNotes(lineElement,line);
            handleLineEvents(lineElement,V.project.getLevelData().getTimeLine(),fakeKeyFrames);
            elements.add(lineElement);
        }
    }

    private static void handleLineNotes(LineElement lineElement,Line line){
        List<NoteElement> noteElements = lineElement.getNoteElements();
        ArrayList<Note> notes = line.getNotes();
        for (Note note : notes) {
            NoteElement noteElement=new NoteElement();
            noteElement.setBackGoing(note.isBackGoing());
            noteElement.setDistanceToLineCenter(note.getDistanceToLineCenter());
            noteElement.setHitTime(note.getBindSample().getAbsTime());
            noteElement.setEndHitTime(
                    note.getBindEndSample()==null?0:note.getBindEndSample().getAbsTime());
            noteElement.setNoteType(NoteElement.NoteType.valueOf(note.getNoteType().name()));
            noteElement.setShown(note.isShown());
            noteElements.add(noteElement);
        }
    }

    private static void handleLineEvents(
            LineElement lineElement, TimeLine timeLine, List<Frame> fakeKeyFrames){
        List<TimeLineRow> timeLineRows = timeLine.getTimeLineRows();
        int num = lineElement.getNum();
        TimeLineRow timeLineRow = getTimeLineRow(timeLineRows, num);
        if (timeLineRow==null) return;
        List<TimeLineEventSet> timeLineEventSets = timeLineRow.getTimeLineEventSets();
        for (TimeLineEventSet timeLineEventSet : timeLineEventSets) {
            fakeKeyFrames.addAll(timeLineEventSet.getKeyFrames());
            timeLineEventSet.getTimeLineEvents().forEach(timeLineEvent ->
                    lineElement.getLineEventElements().add(
                            ((TimeLineLineEvent)timeLineEvent).getLineEventElement()));
        }
        mixKeyFrames(lineElement,timeLine,fakeKeyFrames);
    }

    private static TimeLineRow getTimeLineRow(List<TimeLineRow> timeLineRows,int num){
        for (TimeLineRow timeLineRow : timeLineRows) {
            if (timeLineRow.getBindLineNum()==num) return timeLineRow;
        }
        return null;
    }

    private static void mixKeyFrames(
            LineElement lineElement,TimeLine timeLine,List<Frame> fakeKeyFrames){
        List<Frame> keyFrames = lineElement.getKeyFrames();
        Float fs=null;
        for (Frame fakeKeyFrame : fakeKeyFrames) {
            float time = fakeKeyFrame.getTime();
            if (fs!=null&&time==fs)continue;
            fs=time;
            Frame lineNowFrame = FrameUtil.getLineNowFrame(timeLine, time, lineElement.getNum());
            keyFrames.add(lineNowFrame);
        }
    }*/
}
